#pragma once

#include "curlwork/curlwork.hpp"
#include "curlwork/slist.hpp"

namespace curlwork {

// http://curl.haxx.se/libcurl/c/getinfo.html
template<typename value_type, info_type I>
class basic_info
{
    value_type value_;

public:

    template<typename P>
    basic_info(const P& p)
    {
        error_type e = curl_easy_getinfo(p.handle(), I, &value_);

        if (e != no_error)
            throw std::runtime_error(description(e));
    }

    operator const value_type& () const throw()
    {
        return value_;
    }
} ;

typedef basic_info<const char *, CURLINFO_EFFECTIVE_URL> effective_url;
typedef basic_info<long, CURLINFO_RESPONSE_CODE> response_code;
typedef basic_info<long, CURLINFO_HTTP_CONNECTCODE> connect_code;
typedef basic_info<long, CURLINFO_FILETIME> file_time;
typedef basic_info<double, CURLINFO_TOTAL_TIME> total_time;
typedef basic_info<double, CURLINFO_NAMELOOKUP_TIME> name_lookup_time;
typedef basic_info<double, CURLINFO_CONNECT_TIME> connect_time;
typedef basic_info<double, CURLINFO_APPCONNECT_TIME> app_connect_time;
typedef basic_info<double, CURLINFO_PRETRANSFER_TIME> pre_transfer_time;
typedef basic_info<double, CURLINFO_STARTTRANSFER_TIME> start_transfer_time;
typedef basic_info<double, CURLINFO_REDIRECT_TIME> redirect_time;
typedef basic_info<long, CURLINFO_REDIRECT_COUNT> redirect_count;
typedef basic_info<const char *, CURLINFO_REDIRECT_URL> redirect_url;
typedef basic_info<double, CURLINFO_SIZE_UPLOAD> size_upload;
typedef basic_info<double, CURLINFO_SIZE_DOWNLOAD> size_download;
typedef basic_info<double, CURLINFO_SPEED_DOWNLOAD> speed_download;
typedef basic_info<double, CURLINFO_SPEED_UPLOAD> speed_upload;
typedef basic_info<long, CURLINFO_HEADER_SIZE> header_size;
typedef basic_info<long, CURLINFO_REQUEST_SIZE> request_size;
typedef basic_info<long, CURLINFO_SSL_VERIFYRESULT> ssl_verify_result;
typedef basic_slist<CURLINFO_SSL_ENGINES> ssl_engines;
typedef basic_info<double, CURLINFO_CONTENT_LENGTH_DOWNLOAD>
    content_length_download;
typedef basic_info<double, CURLINFO_CONTENT_LENGTH_UPLOAD>
    content_length_upload;
typedef basic_info<const char *, CURLINFO_CONTENT_TYPE> content_type;
// CURLINFO_PRIVATE - internal using
typedef basic_info<long, CURLINFO_HTTPAUTH_AVAIL> http_auth_avail;
typedef basic_info<long, CURLINFO_PROXYAUTH_AVAIL> proxy_auth_avail;
typedef basic_info<long, CURLINFO_OS_ERRNO> os_errno;
typedef basic_info<long, CURLINFO_NUM_CONNECTS> num_connects;
typedef basic_info<const char *, CURLINFO_PRIMARY_IP> primary_ip;
typedef basic_info<long, CURLINFO_PRIMARY_PORT> primary_port;
typedef basic_info<const char *, CURLINFO_LOCAL_IP> local_ip;
typedef basic_info<long, CURLINFO_LOCAL_PORT> local_port;
typedef basic_slist<CURLINFO_COOKIELIST> cookie_list;
// FIX 32-bit api typedef basic_info<long, CURLINFO_LASTSOCKET> last_socket;
typedef basic_info<const char *, CURLINFO_FTP_ENTRY_PATH> ftp_entry_path;
typedef basic_info<long, CURLINFO_CONDITION_UNMET> condition_unmet;
typedef basic_info<const char *, CURLINFO_RTSP_SESSION_ID> rtsp_sesssion_id;
typedef basic_info<long, CURLINFO_RTSP_CLIENT_CSEQ> rtsp_client_cseq;
typedef basic_info<long, CURLINFO_RTSP_SERVER_CSEQ> rtsp_server_cseq;
typedef basic_info<long, CURLINFO_RTSP_CSEQ_RECV> rtsp_cseq_recv;

} // namespace curlwork
